//
//  Codable+Extension.swift
//  UIKitExtentions
//
//  Created by gupengling on 2021/8/1.
//

import Foundation

///let model1 = ACHomeBanner.decode(dic)
///let model = ACStructDecoder.decode(ACHomeBanner.self, param: dic)

public struct ACStructDecoder {
    //TODO:转换模型(单个)
    public static func decode<T>(_ type: T.Type, param: [String: Any]) -> T? where T: Decodable {
        guard let jsonData = self.getJsonData(with: param) else {
            return nil
        }
        guard let model = try? JSONDecoder().decode(type, from: jsonData) else {
            return nil
        }
        return model
    }

    //多个
    public static func decode<T>(_ type:T.Type, array: [[String: Any]]) -> [T]? where T: Decodable {
        guard let data = self.getJsonData(with: array) else {
            return nil
        }
        guard let models = try? JSONDecoder().decode([T].self, from: data) else {
            return nil
        }
        return models
    }

    public static func getJsonData(with param: Any) ->Data? {
        if !JSONSerialization.isValidJSONObject(param) {
            return nil
        }
        guard let data = try? JSONSerialization.data(withJSONObject: param, options: []) else {
            return nil
        }
        return data
    }
}

public extension Decodable {
    ///dictionary->模型 temp:  Model.decode(dic)
    public static func decode(_ dictionary: [String: Any]) -> Self? {
        guard let data = self.getJsonData(with: dictionary) else {
            return nil
        }
        guard let model = try? JSONDecoder().decode(Self.self, from: data) else {
            return nil
        }
        return model
    }

    ///array->模型 temp:[Model].decode(array)
    public static func decode(_ array: [[String: Any]]) -> Self? {
        guard let data = self.getJsonData(with: array) else {
            return nil
        }
        guard let model = try? JSONDecoder().decode(Self.self, from: data) else {
            return nil
        }
        return model

    }

//    /*
//     如果是单个，则 Model.decode(json)
//     如果是多个，则 [Model].decode(json)
//     */
    public static func getJsonData(with param: Any) -> Data? {
        if !JSONSerialization.isValidJSONObject(param) {
            return nil
        }
        guard let data = try? JSONSerialization.data(withJSONObject: param, options: []) else {
            return nil
        }
        return data
    }
}

///模型转字典
public struct ACStructEncoder {
    public static func encoder<T>(toString model: T) -> String? where T: Encodable {
        let encoder = JSONEncoder()
        encoder.outputFormatting = .prettyPrinted
        guard let data = try? encoder.encode(model) else {
            return nil
        }
        guard let jsonStr = String(data: data, encoding: .utf8) else {
            return nil
        }
        return jsonStr
    }

    public static func encoder<T>(toDictionary model: T) -> [String: Any]? where T: Encodable {
        let encoder = JSONEncoder()
        encoder.outputFormatting = .prettyPrinted
        guard let data = try? encoder.encode(model) else {
            return nil
        }
        guard let dict = try?JSONSerialization.jsonObject(with: data, options: .mutableLeaves) as? [String: Any] else {
            return nil
        }
        return dict
    }
}

public extension Encodable {
    public func encoder() -> Data? {
        let ecd = JSONEncoder()
        ecd.outputFormatting = .prettyPrinted
        return try? ecd.encode(self)
    }
}

public extension Data {
    ///Data->Dictionary
    public func toDictionary() -> [String:Any]?  {
        return try? JSONSerialization.jsonObject(with: self, options: .mutableLeaves) as?  [String: Any]
    }

    ///Data->String
    public func toString() ->String? {
        return String(data:self, encoding: .utf8)
    }

    ///Data->Array
    public func toArrray() -> [Any]? {
        return try? JSONSerialization.jsonObject(with: self, options: .mutableLeaves) as? [Any]
    }
}
